/**
 * Copyright (c) 2022 Presto Labs Pte. Ltd.
 * Author: Ju
 */

#include <assert.h>
#include <glog/logging.h>

#include <cstdint>
#include <nlohmann/json.hpp>
#include <string>
#include <vector>

#include "coin2/base/memory/mem_slice.h"
#include "coin2/base/packer.h"
#include "coin2/base/unpacker.h"

#pragma once

namespace coin2::controller {
using namespace coin2::base::memory;
using nlohmann::json;

struct Packet {
  uint32_t version;
  uint32_t dst_id;
  uint32_t src_id;
  uint32_t encoding;
  uint32_t ttl;
  uint32_t type;
  uint32_t len;
  std::vector<uint8_t> payload;
};

enum MessageType { Json, Msgpack, Protobuf };

enum PayloadType { Heartbeat = 1, APP };

enum DstType { Broadcast };

struct Heartbeat {
  uint32_t node_id;
  std::string node_name;
  int64_t last_seen;
  bool need_reply;
  int seq_num;
};

inline base::Unpacker& operator>>(base::Unpacker& unpk, Packet& pkt) {
  unpk >> pkt.version >> pkt.dst_id >> pkt.src_id >> pkt.encoding >> pkt.ttl >>
      pkt.type >> pkt.payload;
  return unpk;
}

inline base::Packer& operator<<(base::Packer& pk, Packet& pkt) {
  pk << pkt.version << pkt.dst_id << pkt.src_id << pkt.encoding << pkt.ttl
     << pkt.type << pkt.payload;
  return pk;
}

MemSlice MakeResponse(uint32_t src_id, uint32_t dst_id, nlohmann::json payload);

MemSlice SendHeartbeat(uint32_t node_id, std::string node_name,
                       std::string host_name, int64_t pid, int64_t last_seen,
                       bool need_reply, int64_t req_num);

}  // namespace coin2::controller